// https://dvajs.com/API.html#dva-dynamic
// Util method to load React Component and dva model dynamically.

import { Component } from 'react';

// dva umi

// import()
// 动态加载 懒加载组件
// https://github.com/dvajs/dva/blob/master/packages/dva/src/dynamic.js
export function dynamic(config: any) {
  const { app, models: resolveModels, component: resolveComponent } = config;

  return asyncComponent({
    resolve:
      config.resolve ||
      function () {
        const models = typeof resolveModels === 'function' ? resolveModels() : [];
        const component = resolveComponent();
        return new Promise((resolve) => {
          Promise.all([...models, component]).then((ret) => {
            return resolve(ret[0]);
          });
        });
      },
  });
}

function asyncComponent(config: any) {
  const { resolve } = config;
  return class DynamicComponent extends Component<any, any> {
    constructor(...args: any[]) {
      super(...args);
      // loading的组件
      this.LoadingComponent = config.LoadingComponent || defaultLoadingComponent;
      this.state = {
        AsyncComponent: null,
      };
      this.load();
    }

    // load加载
    load() {
      // new Promise().then(res => {})
      resolve().then((m) => {
        const AsyncComponent = m.default || m;
        if (this.mounted) {
          this.setState({ AsyncComponent });
        } else {
          this.state.AsyncComponent = AsyncComponent; // eslint-disable-line
        }
      });
    }

    componentDidMount() {
      // 挂载了
      this.mounted = true;
    }

    componentWillUnmount() {
      this.mounted = false;
    }

    render() {
      // 挂载了之后就会给 AsyncComponent 赋值
      // 如果成功了就渲染 否则就是渲染 loading 组件
      const { AsyncComponent } = this.state;
      const { LoadingComponent } = this;
      if (AsyncComponent) return <AsyncComponent {...this.props} />;

      return <LoadingComponent {...this.props} />;
    }
  };
}

// React.lazy() + import()
// Suspense

// https://github.com/facebook/react/blob/main/packages/react/src/ReactLazy.js
